#ifndef __LOGGER_H__
#define __LOGGER_H__

#include <log4cpp/Category.hh>
#include <string>

using std::string;

class Mylogger {
public:
    static Mylogger *getInstance();

    template <class ...Args>
    void warn(const char *msg, Args ...args) {
        _mycat.warn(msg, args...);
    }

    template <class ...Args>
    void error(const char *msg, Args ...args) {
        _mycat.error(msg, args...);
    }

    template <class ...Args>
    void info(const char *msg, Args ...args) {
        _mycat.info(msg, args...);
    }
    template <class ...Args>
    void debug(const char *msg, Args ...args) {
        _mycat.debug(msg, args...);
    }

private:
    Mylogger();
    ~Mylogger();
    static void init();
    static void destroy();

private:
    static Mylogger *_pInstance;
    log4cpp::Category &_mycat;
    static pthread_once_t _once;
};

#define RESET   "\033[0m"
#define RED     "\033[31m"
#define GREEN   "\033[32m"
#define YELLOW  "\033[33m"
#define BLUE    "\033[34m"

#define prefix(msg) string("[")\
    .append(__FILE__).append(":")\
    .append(__FUNCTION__).append(":")\
    .append(std::to_string(__LINE__)).append("] ")\
    .append(msg).c_str()

#define LogError(msg, ...) Mylogger::getInstance()->error(prefix(RED + std::string(msg) + RESET), ##__VA_ARGS__)
#define LogWarn(msg, ...) Mylogger::getInstance()->warn(prefix(YELLOW + std::string(msg) + RESET), ##__VA_ARGS__)
#define LogInfo(msg, ...) Mylogger::getInstance()->info(prefix(GREEN + std::string(msg) + RESET), ##__VA_ARGS__)
#define LogDebug(msg, ...) Mylogger::getInstance()->debug(prefix(msg), ##__VA_ARGS__)

#endif

